package com.wenx.v3system.modular.cloud.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wenx.v3system.modular.cloud.domain.dto.SysPermissionDto;
import com.wenx.v3system.modular.cloud.domain.maps.SysPermissionMap;
import com.wenx.v3system.modular.cloud.domain.po.SysPermission;
import com.wenx.v3system.modular.cloud.domain.po.SysPermissionCondition;
import com.wenx.v3system.modular.cloud.mapper.SysPermissionConditionMapper;
import com.wenx.v3system.modular.cloud.mapper.SysPermissionMapper;
import com.wenx.v3system.modular.cloud.service.SysPermissionService;
import com.wenx.v3system.modular.cloud.service.SysUserPermissionService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 权限管理核心业务服务实现类
 * 专注于权限条件验证、权限继承、权限树构建等核心业务逻辑
 * 
 * @author wenx
 * @since 1.0.0
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class SysPermissionServiceImpl extends ServiceImpl<SysPermissionMapper, SysPermission> implements SysPermissionService {

    private final SysPermissionConditionMapper permissionConditionMapper;
    private final SysUserPermissionService userPermissionService;
    private final ExpressionParser expressionParser = new SpelExpressionParser();

    // ============= 权限条件验证相关 =============

    @Override
    public boolean validatePermissionConditions(Long userId, String permissionCode, Map<String, Object> context) {
        log.debug("验证用户权限条件，用户ID: {}, 权限代码: {}", userId, permissionCode);
        
        // 获取权限条件配置
        List<SysPermissionCondition> conditions = getPermissionConditions(permissionCode);
        if (CollectionUtils.isEmpty(conditions)) {
            log.debug("权限 {} 无条件限制，直接通过", permissionCode);
            return true;
        }
        
        // 构建评估上下文
        Map<String, Object> evaluationContext = new HashMap<>(context);
        evaluationContext.put("userId", userId);
        evaluationContext.put("permissionCode", permissionCode);
        
        // 验证所有条件（AND逻辑）
        for (SysPermissionCondition condition : conditions) {
            if (!evaluateCondition(condition, evaluationContext)) {
                log.debug("权限条件验证失败，条件: {}-{}-{}", condition.getField(), condition.getOperator(), condition.getValue());
                return false;
            }
        }
        
        log.debug("权限条件验证通过，用户ID: {}, 权限代码: {}", userId, permissionCode);
        return true;
    }

    @Override
    @Cacheable(value = "permission:conditions", key = "#permissionCode")
    public List<SysPermissionCondition> getPermissionConditions(String permissionCode) {
        log.debug("获取权限条件配置，权限代码: {}", permissionCode);
        
        // 首先根据权限代码获取权限ID
        SysPermission permission = getByCode(permissionCode);
        if (permission == null) {
            return new ArrayList<>();
        }
        
        LambdaQueryWrapper<SysPermissionCondition> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysPermissionCondition::getPermissionId, permission.getId())
               .eq(SysPermissionCondition::getStatus, 1) // 启用状态
               .orderByAsc(SysPermissionCondition::getSort);
        
        return permissionConditionMapper.selectList(wrapper);
    }

    @Override
    public boolean evaluatePermissionExpression(String expression, Map<String, Object> context) {
        if (!StringUtils.hasText(expression)) {
            return true;
        }
        
        try {
            StandardEvaluationContext evaluationContext = new StandardEvaluationContext();
            context.forEach(evaluationContext::setVariable);
            
            Expression expr = expressionParser.parseExpression(expression);
            Object result = expr.getValue(evaluationContext);
            
            return Boolean.TRUE.equals(result);
        } catch (Exception e) {
            log.error("权限表达式评估失败，表达式: {}, 错误: {}", expression, e.getMessage());
            return false;
        }
    }

    // ============= 权限继承与层级关系 =============

    @Override
    @Cacheable(value = "permission:parents", key = "#permissionCode")
    public Set<String> getParentPermissions(String permissionCode) {
        log.debug("获取父权限，权限代码: {}", permissionCode);
        
        Set<String> parentCodes = new HashSet<>();
        SysPermission permission = getByCode(permissionCode);
        
        if (permission != null && permission.getParentId() != null) {
            SysPermission parent = getById(permission.getParentId());
            if (parent != null) {
                parentCodes.add(parent.getCode());
                // 递归获取所有父权限
                parentCodes.addAll(getParentPermissions(parent.getCode()));
            }
        }
        
        return parentCodes;
    }

    @Override
    @Cacheable(value = "permission:children", key = "#permissionCode")
    public Set<String> getChildPermissions(String permissionCode) {
        log.debug("获取子权限，权限代码: {}", permissionCode);
        
        Set<String> childCodes = new HashSet<>();
        SysPermission permission = getByCode(permissionCode);
        
        if (permission != null) {
            LambdaQueryWrapper<SysPermission> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(SysPermission::getParentId, permission.getId())
                   .eq(SysPermission::getStatus, 1);
            
            List<SysPermission> children = list(wrapper);
            for (SysPermission child : children) {
                childCodes.add(child.getCode());
                // 递归获取所有子权限
                childCodes.addAll(getChildPermissions(child.getCode()));
            }
        }
        
        return childCodes;
    }

    @Override
    public boolean hasInheritanceRelation(String parentCode, String childCode) {
        Set<String> childPermissions = getChildPermissions(parentCode);
        return childPermissions.contains(childCode);
    }

    // ============= 权限树构建与查询 =============

    @Override
    public List<SysPermissionDto> buildUserPermissionTree(Long userId, String type) {
        log.debug("构建用户权限树，用户ID: {}, 类型: {}", userId, type);
        
        // 获取用户所有权限
        Set<String> userPermissions = userPermissionService.getUserPermissions(userId);
        if (CollectionUtils.isEmpty(userPermissions)) {
            return new ArrayList<>();
        }
        
        // 查询权限数据
        LambdaQueryWrapper<SysPermission> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(SysPermission::getCode, userPermissions)
               .eq(SysPermission::getStatus, 1);
        
        if (StringUtils.hasText(type)) {
            wrapper.eq(SysPermission::getType, type);
        }
        
        wrapper.orderByAsc(SysPermission::getSort);
        
        List<SysPermission> permissions = list(wrapper);
        List<SysPermissionDto> dtoList = SysPermissionMap.INSTANCE.toDtoList(permissions);
        
        return buildTree(dtoList, null);
    }

    @Override
    @Cacheable(value = "permission:tree", key = "#type + ':' + #status")
    public List<SysPermissionDto> buildFullPermissionTree(String type, String status) {
        log.debug("构建完整权限树，类型: {}, 状态: {}", type, status);
        
        LambdaQueryWrapper<SysPermission> wrapper = new LambdaQueryWrapper<>();
        
        if (StringUtils.hasText(type)) {
            wrapper.eq(SysPermission::getType, type);
        }
        if (StringUtils.hasText(status)) {
            wrapper.eq(SysPermission::getStatus, status);
        }
        
        wrapper.orderByAsc(SysPermission::getSort);
        
        List<SysPermission> permissions = list(wrapper);
        List<SysPermissionDto> dtoList = SysPermissionMap.INSTANCE.toDtoList(permissions);
        
        return buildTree(dtoList, null);
    }

    @Override
    public List<SysPermissionDto> getPermissionPath(String permissionCode) {
        log.debug("获取权限路径，权限代码: {}", permissionCode);
        
        List<SysPermissionDto> path = new ArrayList<>();
        SysPermission permission = getByCode(permissionCode);
        
        while (permission != null) {
            path.add(0, SysPermissionMap.INSTANCE.toDto(permission));
            
            if (permission.getParentId() != null) {
                permission = getById(permission.getParentId());
            } else {
                break;
            }
        }
        
        return path;
    }

    // ============= 权限作用域处理 =============

    @Override
    public boolean checkPermissionScope(Long userId, String permissionCode, String scope, Long scopeId) {
        log.debug("检查权限作用域，用户ID: {}, 权限: {}, 作用域: {}, 作用域ID: {}", 
                 userId, permissionCode, scope, scopeId);
        
        // 首先检查用户是否拥有该权限
        if (!userPermissionService.hasPermission(userId, permissionCode)) {
            return false;
        }
        
        // 获取用户在该权限下的作用域范围
        Set<Long> userScopes = getUserPermissionScope(userId, permissionCode);
        
        // 检查作用域权限
        switch (scope.toLowerCase()) {
            case "global":
                return userScopes.contains(-1L); // -1表示全局权限
            case "department":
            case "team":
            case "owner":
                return userScopes.contains(scopeId);
            default:
                return false;
        }
    }

    @Override
    @Cacheable(value = "permission:scope", key = "#userId + ':' + #permissionCode")
    public Set<Long> getUserPermissionScope(Long userId, String permissionCode) {
        log.debug("获取用户权限作用域，用户ID: {}, 权限代码: {}", userId, permissionCode);
        
        // 这里应该根据实际的权限作用域配置来实现
        // 暂时返回全局权限作为示例
        Set<Long> scopes = new HashSet<>();
        scopes.add(-1L); // 全局权限
        
        return scopes;
    }

    // ============= 权限缓存管理 =============

    @Override
    @CacheEvict(value = {"permission:conditions", "permission:parents", "permission:children", 
                        "permission:tree", "permission:scope"}, allEntries = true)
    public void refreshPermissionCache(String permissionCode) {
        log.info("刷新权限缓存，权限代码: {}", permissionCode);
    }

    @Override
    @CacheEvict(value = {"permission:conditions", "permission:parents", "permission:children", 
                        "permission:tree", "permission:scope"}, allEntries = true)
    public void clearPermissionCache() {
        log.info("清除所有权限缓存");
    }

    // ============= 权限统计与分析 =============

    @Override
    public Map<String, Object> getPermissionUsageStats(String permissionCode) {
        log.debug("统计权限使用情况，权限代码: {}", permissionCode);
        
        Map<String, Object> stats = new HashMap<>();
        
        // 统计拥有该权限的角色数量
        // 这里需要根据实际的角色权限关联表来实现
        stats.put("roleCount", 0);
        
        // 统计拥有该权限的用户数量
        stats.put("userCount", 0);
        
        // 统计子权限数量
        Set<String> children = getChildPermissions(permissionCode);
        stats.put("childrenCount", children.size());
        
        return stats;
    }

    @Override
    public List<SysPermissionDto> getOrphanPermissions() {
        log.debug("获取孤立权限列表");
        
        // 查询所有权限
        List<SysPermission> allPermissions = list();
        
        // 这里需要根据实际的角色权限关联表来过滤出孤立权限
        // 暂时返回空列表作为示例
        return new ArrayList<>();
    }

    // ============= 私有辅助方法 =============

    /**
     * 根据权限代码获取权限
     */
    private SysPermission getByCode(String code) {
        LambdaQueryWrapper<SysPermission> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysPermission::getCode, code);
        return getOne(wrapper);
    }

    /**
     * 评估单个权限条件
     */
    private boolean evaluateCondition(SysPermissionCondition condition, Map<String, Object> context) {
        String field = condition.getField();
        String operator = condition.getOperator();
        String value = condition.getValue();
        String contextField = condition.getContextField();
        
        // 获取实际值
        Object actualValue = getActualValue(field, contextField, context);
        
        // 根据操作符进行比较
        return compareValues(actualValue, operator, value);
    }
    
    /**
     * 获取实际值
     */
    private Object getActualValue(String field, String contextField, Map<String, Object> context) {
        if (StringUtils.hasText(contextField)) {
            return getNestedValue(context, contextField);
        }
        return context.get(field);
    }
    
    /**
     * 获取嵌套值，支持 user.departmentId 这样的路径
     */
    private Object getNestedValue(Map<String, Object> context, String path) {
        String[] parts = path.split("\\.");
        Object current = context;
        
        for (String part : parts) {
            if (current instanceof Map) {
                current = ((Map<?, ?>) current).get(part);
            } else {
                return null;
            }
        }
        
        return current;
    }
    
    /**
     * 比较值
     */
    private boolean compareValues(Object actualValue, String operator, String expectedValue) {
        if (actualValue == null) {
            return "is_null".equals(operator);
        }
        
        switch (operator.toLowerCase()) {
            case "=":
            case "eq":
                return Objects.equals(actualValue.toString(), expectedValue);
            case "!=":
            case "ne":
                return !Objects.equals(actualValue.toString(), expectedValue);
            case ">":
                return compareNumeric(actualValue, expectedValue) > 0;
            case ">=":
                return compareNumeric(actualValue, expectedValue) >= 0;
            case "<":
                return compareNumeric(actualValue, expectedValue) < 0;
            case "<=":
                return compareNumeric(actualValue, expectedValue) <= 0;
            case "in":
                return Arrays.asList(expectedValue.split(",")).contains(actualValue.toString());
            case "not_in":
                return !Arrays.asList(expectedValue.split(",")).contains(actualValue.toString());
            case "like":
                return actualValue.toString().contains(expectedValue);
            case "is_null":
                return false; // actualValue不为null时返回false
            default:
                return false;
        }
    }
    
    /**
     * 数值比较
     */
    private int compareNumeric(Object actualValue, String expectedValue) {
        try {
            double actual = Double.parseDouble(actualValue.toString());
            double expected = Double.parseDouble(expectedValue);
            return Double.compare(actual, expected);
        } catch (NumberFormatException e) {
            // 如果不是数值，则按字符串比较
            return actualValue.toString().compareTo(expectedValue);
        }
    }

    /**
     * 构建权限树
     */
    private List<SysPermissionDto> buildTree(List<SysPermissionDto> permissions, Long parentId) {
        return permissions.stream()
                .filter(permission -> Objects.equals(permission.getParentId(), parentId))
                .peek(permission -> {
                    List<SysPermissionDto> children = buildTree(permissions, permission.getId());
                    permission.setChildren(children);
                })
                .collect(Collectors.toList());
    }
}